package com.cdyhsoft.ssodemo.web;

import com.cdyhsoft.ssodemo.model.Result;
import com.cdyhsoft.ssodemo.model.SSOUser;
import com.cdyhsoft.ssodemo.util.HttpClientUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.MessageFormat;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author 黄川 huchuc@vip.qq.com
 * @date: 2018/5/25
 * 描述此类：
 */
@Controller
@RequestMapping(value = "/SSO")
public class SSOController {


    @Value("${sso.uniqueCode}")
    private String uniqueCode;

    @Value("${sso.validatorUrl}")
    private String validatorUrl;

    @Value("${sso.authUrl}")
    private String authUrl;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 模拟账户
     */
    private SSOUser ssoUser = new SSOUser("system", "12316546546556565");

    /**
     * 主系统--- 根据当前登录账户的信息 前往第三方系统
     */
    @GetMapping("/createToken")
    public String createToken() {
        //session中取得用户信息 并生成 短效token
        String token = UUID.randomUUID().toString();
        //将token放入redis中设置时间5分钟失效
        redisTemplate.opsForValue().set(token, ssoUser, 5, TimeUnit.MINUTES);
        return "redirect:" + MessageFormat.format(authUrl, token, uniqueCode);
    }

    /**
     * 单点登录服务器请求认证的地址
     * 主系统--- 验证并返回用户名
     */
    @GetMapping("/Validator")
    @ResponseBody
    public Result validator(@RequestParam(value = "token", defaultValue = "") String tokenid,
                            @RequestParam(value = "uniqueCode", defaultValue = "") String uniqueCode) {
        if ("".equals(tokenid) || "".equals(uniqueCode)) {
            return Result.error("参数不完整");
        }
        if (!redisTemplate.hasKey(tokenid)) {
            return Result.error("验证信息已过期！");
        }
        SSOUser user = (SSOUser) redisTemplate.opsForValue().get(tokenid);
        //执行验证tokenid逻辑
        return Result.sucess(user.getUserName(), user.getIdCard());
    }

    /**
     * 单点登录用户认证的地址
     * 从系统请求我系统-我系统得到token通过后台http访问从系统进行认证，认证成功执行登录逻辑，认证失败返回消息
     */
    @GetMapping("/auth")
    public String auth(@RequestParam(value = "token", defaultValue = "") String token,
                       @RequestParam(value = "uniqueCode", defaultValue = "") String uniqueCode, Model model) {
        if ("".equals(token) || "".equals(uniqueCode)) {
            model.addAttribute("errmsg", "参数不完整");
            return "sso/AuthFailed";
        }
        String url = MessageFormat.format(validatorUrl, token, uniqueCode);
        try {
            HttpClientUtil.Response res = HttpClientUtil.get(url);
            if (res.isOk()) {
                ObjectMapper mapper = new ObjectMapper();
                Result result = mapper.readValue(res.getContent(), Result.class);
                if (result.isSuccess()) {
                    //todo 使用用户名或者身份证号码 执行登录逻辑 登录成功后应该跳转至系统首页
                    model.addAttribute("userName", result.getUserName());
                    return "sso/AuthSucess";
                } else {
                    model.addAttribute("errmsg", result.getErrorMessage());
                    return "sso/AuthFailed";
                }
            } else {
                model.addAttribute("errmsg", "发送认证请求失败！可能是对方服务器无应答！");
                return "sso/AuthFailed";
            }
        } catch (Exception e) {
            model.addAttribute("errmsg", e.getLocalizedMessage());
            return "sso/AuthFailed";
        }
    }

}
